#region imported Namespaces
using System;
using System.Data;
using System.Data.SqlClient;

using BO = PHSRAG.Insight21.BusinessObjects;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
using GenerateKey = PHSRAG.Insight21.BusinessObjects.ModuleKey;
#endregion

namespace PHSRAG.Insight21.Agreements
{
	/// <summary>
	/// The Agreement class is the facade over the details for a single agreement.
	/// </summary>
	public class Agreement : BO.SaveableBusinessObject
	{
		#region Constants
		private static string	AgreementKey = GenerateKey.MakeKey("Agreement_721F635A-B3AD-4c1f-AD5B-913A0AE2F050",GenerateKey.Agreement);
		private const string	TableName = "Agreement";
		#endregion

		#region Instance Variables
		private AgreementProjectDetails	projectDetails;
		#endregion

		#region Public Properties
		/// <summary>
		/// Get the Activity Type. Returns an empty string if no activity type is associated with the agreement.
		/// </summary>
		public string ActivityType
		{
			get	{ return GetAgreementValue("ActivityType"); }
		}

		/// <summary>
		/// Get the Agreement ID.
		/// </summary>
		public int ID 
		{
			get { return (int)DataContainer.Tables[TableName].Rows[0]["AgreementId"]; }
		}

        /// <summary>
        /// Get the Resource ID.
        /// </summary>
        public int ResourceID
        {
            get { return (int)DataContainer.Tables[TableName].Rows[0]["ResourceId"]; }
        }

        /// <summary>
        /// Get the PI ID.
        /// </summary>
        public int PIID
        {
            get 
            {
                object o = DataContainer.Tables[TableName].Rows[0]["PrincipalInvestigatorId"];
                return (o == DBNull.Value) ? 0 : (int)o; 
            }
        }
        
        /// <summary>
		/// Get the Agreement type. Returns an empty string if no type is associated with the agreement.
		/// </summary>
		public string AgreementType
		{
			get	{ return GetAgreementValue("AgreementType"); }
		}

		/// <summary>
		/// Get the Agreement budget end date. Returns an empty string if no end date is associated with the agreement.
		/// </summary>
		public string BudgetEndDate
		{
			get	
			{
				string budgetEnd = GetAgreementValue("BudgetEndDate");
				return (budgetEnd == string.Empty) ? string.Empty : (Convert.ToDateTime(budgetEnd)).ToString("MM/dd/yyyy");
			}
		}

		/// <summary>
		/// Get the Agreement budget start date. Returns an empty string if no start date is associated with the agreement.
		/// </summary>
		public string BudgetStartDate
		{
			get	
			{ 
				string budgetStart = GetAgreementValue("BudgetStartDate");
				return (budgetStart == string.Empty) ? string.Empty : (Convert.ToDateTime(budgetStart)).ToString("MM/dd/yyyy");
			}
		}

		/// <summary>
		/// Get the concatenated version of the budget start/end dates.
		/// </summary>
		public string BudgetStartEndDate
		{
			get	{ return string.Format("{0} -- {1}",
                      (BudgetStartDate == string.Empty || DateTime.Compare(DateTime.Parse(BudgetStartDate), DateTime.Parse("1/1/1900")) == 0) ? string.Empty : BudgetStartDate,
                      (BudgetEndDate == string.Empty || DateTime.Compare(DateTime.Parse(BudgetEndDate), DateTime.Parse("1/1/1900")) == 0) ? string.Empty : BudgetEndDate); }
		}

		/// <summary>
		/// Get the Agreement Fund Number.
		/// </summary>
		public string FundNumber
		{
			get { return GetAgreementValue("FundNumber"); }
		}

		/// <summary>
		/// Get the Agreement Fund Code.
		/// </summary>
		public string FundCode
		{
			get { return GetAgreementValue("FundCode"); }
		}

		/// <summary>
		/// Get the Agreement Fund PreAward Administrator Name.
		/// </summary>
		public string AdminNamePreAward
		{
			get { return GetAgreementValue("AdminNamePreAward"); }
		}

		/// <summary>
		/// Get the Agreement Fund PreAward Administrator Number.
		/// </summary>
		public string AdminNumberPreAward
		{
			get { return GetAgreementValue("AdminNumberPreAward"); }
		}

		/// <summary>
		/// Get the Agreement Fund PostAward Administrator Name.
		/// </summary>
		public string AdminNamePostAward
		{
			get { return GetAgreementValue("AdminNamePostAward"); }
		}

		/// <summary>
		/// Get the Agreement Fund PostAward Administrator Number.
		/// </summary>
		public string AdminNumberPostAward
		{
			get { return GetAgreementValue("AdminNumberPostAward"); }
		}

		/// <summary>
		/// Get the Agreement Sponsor Group Type.
		/// </summary>
		public string SponsorGroupType
		{
			get { return GetAgreementValue("SponsorGroupType"); }
		}

		/// <summary>
		/// Get the Agreement PI name. Returns an empty string if no PI is associated with the agreement.
		/// </summary>
		public string PIName
		{
			get	{ return GetAgreementValue("PIName"); }
		}

		/// <summary>
		/// Get the Agreement project details, creating a loaded one if necessary.
		/// </summary>
		public AgreementProjectDetails ProjectDetails
		{
			get 
			{
				if (projectDetails == null)
				{		
					projectDetails = new AgreementProjectDetails(DataContainer, CachePolicy);
					projectDetails.Load(Utility.DataAccess.ConnectionString, ID);
				}
				return projectDetails;
			}
		}

		/// <summary>
		/// Get the Agreement Project end date. Returns an empty string if no end date is associated with the agreement.
		/// </summary>
		public string ProjectEndDate
		{
			get
			{
				string projectEnd = GetAgreementValue("ProjectEndDate");
				return (projectEnd == string.Empty) ? string.Empty : (Convert.ToDateTime(projectEnd)).ToString("MM/dd/yyyy");
			}
		}

		/// <summary>
		/// Get the Agreement Project start date. Returns an empty string if no start date is associated with the agreement.
		/// </summary>
		public string ProjectStartDate
		{
			get
			{
				string projectStart = GetAgreementValue("ProjectStartDate");
				return (projectStart == string.Empty) ? string.Empty : (Convert.ToDateTime(projectStart)).ToString("MM/dd/yyyy");
			}
		}

		/// <summary>
		/// Get the concatenated version of the project start/end dates.
		/// </summary>
		public string ProjectStartEndDate
		{
			get { return string.Format("{0} -- {1}",
                      (ProjectStartDate == string.Empty || DateTime.Compare(DateTime.Parse(ProjectStartDate), DateTime.Parse("1/1/1900")) == 0) ? string.Empty : ProjectStartDate,
                      (ProjectEndDate == string.Empty || DateTime.Compare(DateTime.Parse(ProjectEndDate), DateTime.Parse("1/1/1900")) == 0) ? string.Empty : ProjectEndDate); }
		}

		/// <summary>
		/// Get the Agreement sponsor name.
		/// </summary>
		public string SponsorName
		{
			get { return GetAgreementValue("SponsorName"); }
		}

		/// <summary>
		/// Get the Agreement status type. Returns an empty string if no status type is associated with the agreement.
		/// </summary>
		public string StatusType
		{
			get	{ return GetAgreementValue("StatusType"); }
		}

		/// <summary>
		/// Get/Set the Agreement title.
		/// </summary>
		public string Title
		{
			get { return GetAgreementValue("Title"); }
			set { DataContainer.Tables[TableName].Rows[0]["Title"] = value;	}
		}
		public string SponsorTypeName
		{
			get { return GetAgreementValue("SponsorTypeName"); }
		}

		public string ICBasis
		{
			get { return GetAgreementValue("ICBasis"); }
		}

		public string FinanceContactName
		{
			get { return GetAgreementValue("FinanceContactName"); }
		}

		public string FinanceContactNumber
		{
			get { return GetAgreementValue("FinanceContactNumber"); }
		}

		public string FinanceContactEmail
		{
			get { return GetAgreementValue("FinanceContactEmail"); }
		}
		#endregion

		#region Constructors
		/// <summary>
		/// Initialize the base class with the specified cache policy and create the data container.
		/// </summary>
		public Agreement(ICachePolicy cachePolicy) : base(cachePolicy)
		{
			DataContainer = new DataSet();
		}
		#endregion

		#region Base Methods
		/// <summary>
		/// Cache this instance using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(AgreementKey, this);
		}

		/// <summary>
		/// Remove this instance from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(AgreementKey);
		}

		/// <summary>
		/// Load details pertaining to a specific agreement ID.
		/// </summary>
		/// <param name="connection">Connection string to the database</param>
		/// <param name="args">Contains the agreement ID and, optionally, the fund number</param>
		public override void Load(string connectionString, params object[] args)
		{
			if (args.Length != 1 && args.Length != 2)
				throw new Exception ("Agreement Load expects Agreement ID and FundNumber (nullable).");

			int agreementID = (int)args[0];
			string fundNumber = null;
			if (args.Length == 2)
				fundNumber = (string)args[1];

			try
			{
				DataContainer.Reset();
			
				Utility.DataAccess.LoadDataSet(DataContainer, TableName, connectionString, "GetAgreementSummary",
					Utility.DataAccess.BuildSqlParameterArray(
						"@agreementId", SqlDbType.Int, agreementID,
						"@fundNumber", SqlDbType.VarChar, fundNumber));
			}
			catch( Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog("Agreement Load", e, true, Utility.ExceptionReport.ReportType.Error);
			}
		}

		/// <summary>
		/// Saves project details associated with this agreement.
		/// </summary>
		/// <param name="connectionString">Connection string to the database</param>
		/// <param name="args">Optional parameters (ignored)</param>
		public override void Save(string connectionString, params object[] args)
		{
			ProjectDetails.Save(connectionString);
		}

        /// <summary>
        /// This method is used to fetch key contacts for Insitution and ChiefCode
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="institution"></param>
        /// <param name="chiefCode"></param>
        /// <returns></returns>
        public static DataTable GetKeyContacts(string connectionString, string institution, string chiefCode,string sponsorTypeId)
        {
            return Utility.DataAccess.GetDataTable(connectionString, "GetKeyContacts",
                        Utility.DataAccess.BuildSqlParameterArray(
                        "@inst", SqlDbType.VarChar, institution,
                        "@chiefCode",SqlDbType.VarChar,chiefCode,
                        "@sponsorTypeId",SqlDbType.VarChar,sponsorTypeId));
        
        }
		#endregion

		#region Private Helpers
		private string GetAgreementValue(string columnName)
		{
			object o = DataContainer.Tables[TableName].Rows[0][columnName];
			return (o == DBNull.Value) ? string.Empty : o.ToString();
		}
		#endregion
	}
}

